package com.algo.config.db;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(-1)
@Component
public class DataSourceAop {

    Logger logger = LoggerFactory.getLogger(DataSourceAop.class);

    @Pointcut("@annotation(com.algo.config.db.Slave1)")
    public void readPointcut() {
    }

    @Pointcut("@annotation(com.algo.config.db.Master)")
    public void writePointcut() {
    }

    @Around("readPointcut()")
    public Object read(ProceedingJoinPoint point) throws Throwable {

        try {
            MyRoutingDataSource.setDataSource(DBTypeEnum.SLAVE1);

            if (logger.isDebugEnabled()) {
                logger.debug(">>>>>>switch datasource to slave");
            }
            return point.proceed();
        } finally {
            MyRoutingDataSource.clearDataSource();
            if (logger.isDebugEnabled()) {
                logger.debug(">>>>>>clean slave datasource");
            }
        }
    }

    @Around("writePointcut()")
    public Object write(ProceedingJoinPoint point) throws Throwable {
        try {
            MyRoutingDataSource.setDataSource(DBTypeEnum.MASTER);

            if (logger.isDebugEnabled()) {
                logger.debug(">>>>>>switch datasource to master");
            }
            return point.proceed();
        } finally {
            MyRoutingDataSource.clearDataSource();
            if (logger.isDebugEnabled()) {
                logger.debug(">>>>>>clean master datasource");
            }
        }
    }
}
